package logic

import (
	"fmt"
	"github.com/gogap/logs"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"math/rand"
	"sort"
	"strings"
	"time"
	"yundian/internel/app/dao"
	"yundian/internel/app/dao/memberdao"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/membermodel"
	"yundian/internel/app/models/users"
	"yundian/internel/app/models/wifimodel"
	"yundian/internel/pkg/dbs"
	"yundian/internel/pkg/dingo"
)

type WifiLogic struct {
}

func NewWifiLogic() *WifiLogic {
	return &WifiLogic{}
}

// 广告收益算法
func (logic *WifiLogic) AdIncomeCompute(param *request.AdIncomeReq) float64 {

	// 获取广告单价
	var info *wifimodel.WifiAdSetting
	dateStr := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
	info = dao.NewWifiDao().GetAdSettingInfo(dateStr).Unwrap().(*wifimodel.WifiAdSetting)
	if info.ID == 0 {
		dateStr := time.Now().AddDate(0, 0, -2).Format("2006-01-02")
		info = dao.NewWifiDao().GetAdSettingInfo(dateStr).Unwrap().(*wifimodel.WifiAdSetting)
	}
	//log.Println("广告收益配置详情", info, info.AdMinPrice, info.AdMaxPrice)

	// 获取最新一笔订单
	orderInfo := dao.NewWifiDao().GetLastAdOrder(param.OpenId, param.Appid).Unwrap().(*wifimodel.AdOrderModel)

	// 获取随机价格
	var rLst []float64
	if orderInfo.Id == 0  { // 新UV
		rand.Seed(time.Now().UnixNano())
		rLst = helper.RandFloats(info.AdMinPrice, info.AdMaxPrice*0.8, 1)
	} else { // 旧UV
		rand.Seed(time.Now().UnixNano())
		rLst = helper.RandFloats(info.AdMinPrice, info.AdMaxPrice*0.6, 1)
	}

	//log.Println(rLst)

	if rLst[0] > 0 {
		return rLst[0]
	}
	return 0
}

func (logic *WifiLogic) AddIncome(tradeNo string, adIncome float64, curruserInfo *users.WifiUserDetail, devInfo *devices.DeviceType, param *request.AdIncomeReq, clientIp string)  {
	createAt := dingo.Time(time.Now().Unix())
	dateStr := time.Now().Format("2006-01-02")
	memInfo := memberdao.NewMemberDao().GetMemberInfoByOpenidAndAppId(param.OpenId, param.Appid).Unwrap().(*membermodel.MembersModel)
	if memInfo.ID == 0 {
		return
	}
	var err error
	var userList []*users.WifiUserDetail
	userList = append(userList, curruserInfo)

	if userList, err = logic.QueryWifiUserParentListAll(curruserInfo, userList, 0); err != nil {
		logs.Error("CalAgentBonus->QueryParentListAll", err)
		return
	}

	userList = logic.RepetitionWifiUserList(userList)
	sort.Slice(userList, func(i, j int) bool {
		if userList[i].ProfitProportion != userList[j].ProfitProportion {
			return userList[i].ProfitProportion < userList[j].ProfitProportion
		}

		IsAdmins := fmt.Sprintf("[%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]",
			helper.TypeNumIsAdminMerchant, helper.TypeNumIsAdminBd, helper.TypeNumIsAdminKaProject, helper.TypeNumIsAdminRegion, helper.TypeNumIsAdminResource,
			helper.TypeNumIsAdminStaff, helper.TypeNumIsAdminPartner, helper.TypeNumIsAdminBranch, helper.TypeNumIsAdminOperator, helper.TypeNumIsAdminAdministrator)
		iIndex := strings.Index(IsAdmins, fmt.Sprintf("[%d]", userList[i].IsAdmin))
		jIndex := strings.Index(IsAdmins, fmt.Sprintf("[%d]", userList[j].IsAdmin))
		return iIndex < jIndex
	})

	var profit int64

	tx, key := dbs.GormBegin("CalAgentBonus")
	// 创建订单
	adOrder := &wifimodel.AdOrderModel{}
	adOrder.Appid = param.Appid
	adOrder.Openid = param.OpenId
	adOrder.TradeNo = tradeNo
	adOrder.DeviceSn = devInfo.DeviceSn
	adOrder.UserId = curruserInfo.UserId
	adOrder.UserName = curruserInfo.Name
	adOrder.Money = decimal.NewFromFloat(adIncome).Mul(decimal.NewFromInt(100)).IntPart()
	adOrder.PlaceId = devInfo.PlaceId
	adOrder.PlaceName = devInfo.PlaceName
	adOrder.MemberId = memInfo.ID
	adOrder.MemberName = memInfo.NickName
	adOrder.IsDraw = 0
	adOrder.Phone = memInfo.Phone
	adOrder.CreateAt = createAt
	adOrder.DateStr = dateStr

	if err = logic.InsertAdOrder(tx, adOrder); err != nil {
		dbs.GormRollback(tx, key, err)
		return
	}
	// 分红
	for index, item := range userList {
		logs.Info("userList - info", item, item.UserId, item.UserName, item.ProfitProportion, item.IsAdmin, item.IsDivinds)
		ad := &wifimodel.AdIncomeModel{}
		ad.TradeNo = tradeNo
		ad.AdType = param.AdType
		ad.IncomeType = param.IncomeType
		ad.Appid = param.Appid
		ad.Unionid = param.Unionid
		ad.Openid = param.OpenId
		ad.PlaceId = devInfo.PlaceId
		ad.PlaceName = devInfo.PlaceName
		ad.DeviceSn = devInfo.DeviceSn
		ad.ClientIp = clientIp
		ad.CreateAt = createAt
		ad.DateStr = dateStr

		ad.UserId = item.UserId
		ad.UserName = item.Name
		if index > 0 {
			profit = int64(userList[index-1].ProfitProportion)
		}
		lastProfit := decimal.NewFromInt(int64(profit))
		curruserProfit := decimal.NewFromInt(int64(item.ProfitProportion))
		money := decimal.NewFromFloat(adIncome)
		adPrice, _ := curruserProfit.Sub(lastProfit).Mul(money).Div(decimal.NewFromInt(100)).Float64()
		ad.AdPrice = adPrice

		// 添加分红记录
		if err = logic.InsertAdIncomeLog(tx, ad); err != nil {
			dbs.GormRollback(tx, key, err)
			return
		}
	}
	dbs.GormCommit(tx, key)
}

func (logic *WifiLogic) InsertAdIncomeLog(tx *gorm.DB, ad *wifimodel.AdIncomeModel) error {
	if result := dao.NewWifiDao().InsertAdIncome(tx, ad); result.Err != nil {
		return result.Err
	}
	return nil
}

func (logic *WifiLogic) InsertAdOrder(tx *gorm.DB, order *wifimodel.AdOrderModel) error {
	if result := dao.NewWifiDao().InsertAdOrder(tx, order); result.Err != nil {
		return result.Err
	}
	return nil
}

// 查询所有参与分红的用户
func (logic *WifiLogic) QueryWifiUserParentListAll(userInfo *users.WifiUserDetail, userList []*users.WifiUserDetail, num int) ([]*users.WifiUserDetail, error) {
	num++
	if userInfo.ParentId <= 0 || num > 100 {
		return userList, nil
	}

	resultUserInfo := memberdao.NewMemberDao().GetWifiUserInfoByUserId(userInfo.ParentId)
	if resultUserInfo.Err != nil {
		return userList, resultUserInfo.Err
	}

	targetUserInfo := resultUserInfo.Unwrap().(*users.WifiUserDetail)
	userList = append(userList, targetUserInfo)

	return logic.QueryWifiUserParentListAll(targetUserInfo, userList, num)
}

// 层级用户去重复
func (logic *WifiLogic) RepetitionWifiUserList(userList []*users.WifiUserDetail) (list []*users.WifiUserDetail) {
	m := map[int]bool{}
	for _, item := range userList {
		if m[item.UserId] || item.IsDivinds == helper.TypeNumDividendsStatusNo {
			continue
		}
		list = append(list, item)
		m[item.UserId] = true
	}

	return list
}
